/*
 * @Descripttion: 路由权限相关
 * @version:
 * @Author: lhl
 * @Date: 2024-09-14 15:44:13
 * @LastEditors: lhl
 * @LastEditTime: 2024-09-19 17:25:49
 */
import { defineStore } from 'pinia';
import { constantRoutes } from '@/router';
import { RouteRecordRaw } from 'vue-router';
import API from '@/api';

interface PermissionState {
  routes: RouteRecordRaw[];
  addRoutes: RouteRecordRaw[];
}

const modules = import.meta.glob('../views/**/**.vue');

export const Layout = () => import('@/layout/Index.vue');

const hasPermission = (roles: string[], route: RouteRecordRaw) => {
  // 如果路由没有角色限制，默认返回 false
  const routeRoles = route.meta?.roles;
  if (!routeRoles) {
    return false;
  }

  // 如果用户角色中包含 ROOT，直接返回 true
  if (roles.includes('ROOT')) {
    return true;
  }

  // 检查用户角色是否与路由限制角色匹配
  return roles.some((role) => routeRoles.includes(role));
};

/**
 * 过滤异步路由表
 * @param routes 路由数组
 * @param roles 用户角色数组
 * @returns 返回过滤后的路由数组
 */
export const filterAsyncRoutes = (routes: RouteRecordRaw[], roles: string[]) => {
  const asyncRoutes: RouteRecordRaw[] = [];
  routes.forEach((route) => {
    const tmp = { ...route } as any;
    if (hasPermission(roles, tmp)) {
      if (tmp.component?.toString() === 'Layout') {
        tmp.component = Layout;
      } else {
        const component = modules[`../views/${tmp.component}.vue`];
        if (component) {
          tmp.component = component;
        } else {
          tmp.component = modules[`@/views/error-page/404.vue`];
        }
      }
      asyncRoutes.push(tmp);

      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, roles);
      }
    }
  });
  return asyncRoutes;
};

export const usePermissionStore = defineStore('permission', {
  // 相当于data
  state: (): PermissionState => ({
    routes: [],
    addRoutes: []
  }),
  // 相当于vuex的 mutation + action，可以同时写同步和异步的代码
  actions: {
    setRoutes(routes: RouteRecordRaw[]) {
      this.addRoutes = routes;
      this.routes = constantRoutes.concat(routes);
    },
    generateRoutes(roles: string[]) {
      return new Promise((resolve, reject) => {
        API.system
          .menuApi({})
          .then((response) => {
            const asyncRoutes = response.data;
            const accessedRoutes = filterAsyncRoutes(asyncRoutes, roles);
            this.setRoutes(accessedRoutes);
            resolve(accessedRoutes);
          })
          .catch((error) => {
            reject(error);
          });
      });
    }
  }
  // 配合pinia-plugin-persist插件 持久化 默认存储到 sessionStorage ，key 为 store 的 id
  // persist: {
  //   enabled: true,
  //   strategies: [
  //     { storage: sessionStorage, paths: ['counter'] }, // counter字段用 sessionStorage 存储
  //     { storage: localStorage, paths: ['name'] } // name 字段用 localstorage 存储
  //   ]
  // }
});
